﻿using SIR.Common;
using SIR.Common.Condition;
using SIR.Entities.Interfaces;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;

namespace SIR.Entities.Implementations
{
	/// <summary>
	/// Represents a folder containing images and subfolders
	/// </summary>
	public class Folder : Entity, IFolder
	{
		/// <summary>
		/// Creates a folder with the default name of "New Folder"
		/// </summary>
		public Folder()
			: base()
		{
			Name = "New Folder";
		}

		private IReadOnlyCollection<IImage> _images;
		private IReadOnlyCollection<IFolder> _folders;

		/// <summary>
		/// Gets or sets the name of the folder
		/// </summary>
		[DatabaseAccess(DatabaseAccessRights.ReadWrite)]
		public string Name { get; set; }
		/// <summary>
		/// Gets or sets the user id for the folder
		/// </summary>
		[DatabaseAccess(DatabaseAccessRights.ReadWrite)]
		public long UserId { get; set; }
		/// <summary>
		/// Gets or sets the parent folder id for the folder
		/// </summary>
		[DatabaseAccess(DatabaseAccessRights.ReadWrite)]
		public long ParentFolderId { get; set; }
		/// <summary>
		/// Gets the images contained within the folder
		/// </summary>
		[Newtonsoft.Json.JsonIgnore]
		[DatabaseAccess(DatabaseAccessRights.None)]
		public IReadOnlyCollection<IImage> Images
		{
			get
			{
				if (_images == null)
				{
					_images = new ReadOnlyCollection<Image>(DAL.DataServer.Find<Image>(new PredicateGroup(new[] { 
						new Predicate("UserId", UserId, PredicateOperator.EqualTo),
						new Predicate("FolderId", Id, PredicateOperator.EqualTo)
					}, true)).Results);
				}
				return _images;
			}
		}
		/// <summary>
		/// Gets the subfolders contained within the folder
		/// </summary>
		[DatabaseAccess(DatabaseAccessRights.None)]
		public IReadOnlyCollection<IFolder> Folders
		{
			get
			{
				if (_folders == null)
				{
					_folders = new ReadOnlyCollection<Folder>(DAL.DataServer.Find<Folder>(new PredicateGroup(new[] { 
						new Predicate("UserId", UserId, PredicateOperator.EqualTo),
						new Predicate("ParentFolderId", Id, PredicateOperator.EqualTo)
					}, true)).Results);
				}
				return _folders;
			}
		}
		/// <summary>
		/// Gets the number of items contained within the folder
		/// </summary>
		/// <returns>The number of images</returns>
		public uint ItemsCount()
		{
			return (uint)(Images.Count() + Folders.Count());
		}
		/// <summary>
		/// Gets the number of images contained within this folder and all folders underneath it
		/// </summary>
		/// <returns>The number of images</returns>
		public uint GetNumberOfImagesInTree()
		{
			var count = (uint)Images.Count;
			foreach (var folder in Folders)
				count += folder.GetNumberOfImagesInTree();
			return count;
		}
		/// <summary>
		/// Gets whether or not the image is set to private
		/// </summary>
		[DatabaseAccess(DatabaseAccessRights.ReadWrite)]
		public bool IsPrivate { get; set; }
		/// <summary>
		/// Gets whether ot not the parent folder is private
		/// </summary>
		[DatabaseAccess(DatabaseAccessRights.Read)]
		public bool IsParentFolderPrivate { get; set; }
	}
}

